import chinaAreaData from './data.json';
import type { CascaderOption } from 'element-plus';

// 省市区数据结构化定义类型
interface ChinaArr {
  label: string;
  parent?: string;
  value: string;
}
// 递归输入参数
interface InRecursion {
  ssq: Record<string, string>;
  leave?: number;
  custom?: CascaderOption;
}
interface ChinaAreaInput {
  leave: number;
  isall: boolean;
  customItem?: CascaderOption[];
  after?: boolean;
}
type ChinaAreaflat = Record<string, ChinaArr>;

class ChinaArea {
  public chinaAreaData = chinaAreaData;

  public chinaAreaflat: ChinaAreaflat; // 对象改平之后的结构，用于数据取值

  public leave = 3; // 控制递归层级

  public isall = false; // 是否需要全部选项

  /**
   * 将数组结构转化为对象结构
   */
  public chinaObj() {
    const list: ChinaAreaflat = {};
    for (const key in chinaAreaData) {
      const area = chinaAreaData[key as keyof typeof chinaAreaData];
      for (const i in area) {
        const item: ChinaArr = {
          label: area[i as keyof typeof area],
          value: i,
        };
        if (key !== '86') {
          item.parent = key;
        }
        list[i] = item;
      }
    }
    return list;
  }

  public constructor({ leave = 0, isall = false }: ChinaAreaInput = {} as ChinaAreaInput) {
    this.leave = leave;
    this.isall = isall;
    this.chinaAreaflat = this.chinaObj();
  }

  // 省市区数据格式化
  public chinaData() {
    const province = chinaAreaData[86];
    const opt: InRecursion = { ssq: province };
    if (this.isall) {
      opt.custom = {
        label: '全部',
        value: 'all',
      };
    }
    return this.recursion(opt);
  }

  // 递归得到省市区三级数据
  private recursion({ ssq, leave = 0, custom }: InRecursion) {
    const layer = leave + 1;
    const reprovince: CascaderOption[] = [];
    if (layer > this.leave) {
      return reprovince;
    }

    custom && reprovince.push(custom);
    for (const i in ssq) {
      const item: CascaderOption = {
        label: ssq[i] || '',
        value: i,
        leave: layer,
      };
      const area = chinaAreaData[i as keyof typeof chinaAreaData];
      if (chinaAreaData) {
        item.children = this.recursion({ ssq: area, leave: layer, custom });
      }
      reprovince.push(item);
    }
    return reprovince;
  }
}

export default ChinaArea;
